﻿using System;
using System.Collections.Generic;
using DullBoard.Helper;
using DullBoard.Model;
using HtmlAgilityPack;

namespace DullBoard.Deserializers
{
    public static class ThreadDeserializer
    {
        public static Post DeserializePost(this HtmlNode threadNode)
        {
            var post = new Post();

            post.Id = Int64.Parse(threadNode.Attributes["id"].Value.Replace("post-", ""));
            post.BlizzardPost = threadNode.Attributes["class"].Value.Contains("blizzard");
            post.Author = threadNode.SelectSingleNode(threadNode.XPath + "//div[@class=\"post-user\"]").DeserializeUser(post.BlizzardPost);
            post.Ordinal = Int32.Parse(threadNode.SelectSingleNode(threadNode.XPath + "//span[1]").Attributes["id"].Value);
            post.Detail = threadNode.SelectSingleNode(threadNode.XPath + "//div[@class=\"post-detail\"]").DeserializePostDetail();

            var postDate = threadNode.SelectSingleNode(threadNode.XPath + "//div[@class=\"date\"]").Attributes["data-tooltip"].Value;
            post.Date = postDate.DeserializeDate();

            return post;
        }

        public static List<PostDetail> DeserializePostDetail(this HtmlNode postDetailNode)
        {
            var postDetails = new List<PostDetail>();

            int ordinal = 1;
            foreach (var child in postDetailNode.ChildNodes)
            {
                switch (child.Name.ToLower())
                { 
                    case "#text":
                        {
                            var pd = new PostDetail();
                            pd.Ordinal = ordinal;
                            pd.IsQuote = false;
                            pd.Text = child.InnerText.Trim().RemoveNonAscii();

                            if (pd.Text.Length != 0)
                            {
                                postDetails.Add(pd);
                                ordinal++;
                            }

                            break;
                        }
                    case "blockquote":
                        {
                            var pd = new PostDetail();
                            pd.Ordinal = ordinal;
                            pd.IsQuote = true;

                            var playerQuote = child.SelectSingleNode(child.XPath + "//div[1]/span[@class=\"bml-quote-date\"]");
                            if (playerQuote != null)
                            {
                                pd.QuoteDate = playerQuote.InnerText.Trim().RemoveNonAscii();
                                pd.QuoteName = child.SelectSingleNode(child.XPath + "//div[1]/a").InnerText.Trim().RemoveNonAscii();
                                pd.Text = child.ChildNodes[1].InnerText.Trim().RemoveNonAscii();
                            }
                            else
                            {
                                pd.Text = child.ChildNodes[0].InnerText.Trim().RemoveNonAscii();
                            }
                            postDetails.Add(pd);
                            ordinal++;
                            break;
                        }
                    case "br":
                        {
                            var pd = new PostDetail();
                            pd.Ordinal = ordinal;
                            pd.IsLineBreak = true;
                            postDetails.Add(pd);
                            ordinal++;
                            break;
                        }
                }
            }


            return postDetails;
        }

        public static User DeserializeUser(this HtmlNode userNode, bool blizzardUser = false)
        {
            var user = new User();

            if (!blizzardUser)
            {
                user.Name = userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"user-name\"]/span[@class=\"char-name-code\"]").InnerText.Trim();
                user.Realm = userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"ui-context\"]/div[@class=\"context\"]/div[@class=\"context-user\"]/span[1]").InnerText.Trim();
                user.AchievementPoints = Int32.Parse(userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"achievements\"]").InnerText.Trim());
                user.CharacterInfo = userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"character-desc\"]/span[1]").InnerText.Trim();

                var guildNode = userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"guild\"]/a[1]");
                if (guildNode != null)
                    user.Guild = guildNode.InnerText.Trim();
            }
            else
            {
                user.Name = userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"user-name\"]/span[@class=\"char-name-code\"]").InnerText.Trim();
                user.BlizzardUser = true;
                user.BlizzardTitle = userNode.SelectSingleNode(userNode.XPath + "//div[@class=\"blizzard-title\"]").InnerText.Trim();
            }


            return user;
        }

    }
}
